/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.miscellaneous.io;

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.IOException;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import phoside.util.IOUtil;
import phoside.util.UrlUtil;

/**
 *
 * @author gjj
 */
public class PhosphoPepExtractor {
    private String baseUrl;
    private String listPage;

    public PhosphoPepExtractor(String baseUrl) {
        this(baseUrl, baseUrl+"browse_glycopeptides.cgi");
    }

    public PhosphoPepExtractor(String baseUrl, String listPage) {
        this.baseUrl = baseUrl;
        this.listPage = listPage;
    }

    public void download(String dirTo) throws IOException {
        List<String> strOut = new ArrayList();

        String line = lineOfEntries();
        List<List<String>> table = readListTable(line);
        int n = table.size();
        for (int i=1; i<n; i++) {
            if (i%10==0) break;
                System.out.println(String.format("%5d/%-5d", i, n));
            List<String> row = table.get(i);
            String str = row.get(0);
            int ix = str.indexOf("\">",9);
            String page = str.substring(9,ix);
            page = page.replace("&amp;", "&");
            String acc = str.substring(ix+2,str.length()-4);

            strOut.add(">"+acc+"\t"+baseUrl+page);
            List<String[]> peps = getPeptides(page);
            for (String[] pep : peps) {
                strOut.add(pep[0]+"\t"+pep[1]+"\t"+pep[2]);
            }
        }

        IOUtil.writeCollectionAscii(strOut, dirTo);
    }

    private List<String[]> getPeptides(String entryPage) throws IOException {
        String line = lineOfSites(entryPage);
        line = line.replace("<td>", "@");
        line = line.replace("</td>", "@");
        List<String[]> peps = new ArrayList();

        Pattern p = Pattern.compile("@([^@]*<SPAN class=[^>]*phospho NAME=[^>]*phospho ID=[^>]*phospho>.\\0052</SPAN>[^@]*)@[^<]*" +
                "<td align=\"right\">([^@]+)@[^@]+@[^@]+@[^<]*<td align=\"right\">([^@]+)@");
        Matcher m = p.matcher(line);
        while (m.find()) {
            String pep = m.group(1).toUpperCase();
            pep = pep.replaceAll("<SPAN CLASS=PHOSPHO NAME=PHOSPHO ID=PHOSPHO>(.)\\052</SPAN>", "p$1");
            pep = pep.replaceAll("<SPAN CLASS=AMBIPHOSPHO NAME=AMBIPHOSPHO ID=AMBIPHOSPHO>(.)\\0052</SPAN>", "a$1");
//            int s = pep.indexOf('.');
//            int t = pep.indexOf('.', s+1);
//            pep = pep.substring(s+1, t);
            String score = m.group(2);
            String deltacn = m.group(3);

            peps.add(new String[]{pep,score,deltacn});
        }

        return peps;
    }

    private String lineOfSites(String entryPage) throws IOException {
        String page = baseUrl + entryPage;
        List<String> lines = readPage(page);
        int n = lines.size();
        String line;
        for (int i=0; i<n; i++) {
            line = lines.get(i);
            int idx = line.indexOf("<SPAN class=phospho NAME=phospho ID=phospho>");
            if (idx>=0) {
                return line;
            }

            idx = line.indexOf("<SPAN class=ambiphospho NAME=ambiphospho ID=ambiphospho>");
            if (idx>=0) {
                return line;
            }
        }

        return null;
    }

    private String lineOfEntries() throws IOException {
        List<String> lines = readPage(listPage);
        int n = lines.size();
        String line;
        for (int i=0; i<n; i++) {
            line = lines.get(i);
            int idx = line.indexOf("Accession");
            if (idx>=0) {
                idx = line.indexOf("Protein Name",idx);
                if (idx>=0) {
                    return line;
                }
            }
        }

        return null;
    }

    private List<String> readPage(String page) throws IOException {
        InputStream is = UrlUtil.getInputStream(page);
        InputStreamReader isr = new InputStreamReader(is);
        return IOUtil.readStringListAscii(isr);
    }

    private static List<List<String>> readListTable(String line) {
        String lineCopy = line.replaceAll("<table[^>]*>", "");
        lineCopy = line.replaceAll("<TABLE[^>]*>", "");
        lineCopy = line.replaceAll("<tbody>", "");
        lineCopy = line.replaceAll("<TBODY>", "");
        lineCopy = line.replaceAll("</table>", "");
        lineCopy = line.replaceAll("</TABLE>", "");
        lineCopy = lineCopy.replaceAll("<t[rd][^>]*>", "");
        lineCopy = lineCopy.replaceAll("<T[RD][^>]*>", "");
        lineCopy = lineCopy.replaceAll("</TR>", "</tr>");
        lineCopy = lineCopy.replaceAll("</TD>", "</td>");
        
        List<List<String>> table = new ArrayList();

        String[] trs = lineCopy.split("</tr>");
        for (String tr : trs) {
            String[] tds = tr.trim().split("</td>");
            List<String> row = new ArrayList();
            for (String td : tds) {
                row.add(td.trim());
            }
            table.add(row);
        }

        return table;
    }

    public static void main(String[] args) {
//
//        // fly
//        String baseUrl = "http://www.sbeams.org/dev1/sbeams/cgi/Glycopeptide/";
//        PhosphoPepDownloader downloader = new PhosphoPepDownloader(baseUrl);
//        String dirPep = "D:\\projects\\PHOSIDE\\PHOSIDE\\data\\processing\\PhosphoPep-fly-10022009.pep";

        // worm
        String baseUrl = "";
        String listPage = "file:///D:/projects/PHOSIDE/PHOSIDE/data/processing/Phosphopep-worm-10022009.html";
        PhosphoPepExtractor downloader = new PhosphoPepExtractor(baseUrl,listPage);
        String dirPep = "D:\\projects\\PHOSIDE\\PHOSIDE\\data\\processing\\PhosphoPep-worm-10022009.pep";

        try {
            downloader.download(dirPep);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // yeast
        listPage = "file:///D:/projects/PHOSIDE/PHOSIDE/data/processing/Phosphopep-yeast-10022009.html";
        PhosphoPepExtractor downloader1 = new PhosphoPepExtractor(baseUrl,listPage);
        String dirPep1 = "D:\\projects\\PHOSIDE\\PHOSIDE\\data\\processing\\PhosphoPep-yeast-10022009.pep";

        try {
            downloader1.download(dirPep1);
        } catch (Exception e) {
            e.printStackTrace();
        }

        // human
        listPage = "file:///D:/projects/PHOSIDE/PHOSIDE/data/processing/Phosphopep-human-10022009.html";
        PhosphoPepExtractor downloader2 = new PhosphoPepExtractor(baseUrl,listPage);
        String dirPep2 = "D:\\projects\\PHOSIDE\\PHOSIDE\\data\\processing\\PhosphoPep-human-10022009.pep";

        try {
            downloader2.download(dirPep2);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }



}
